package com.minew.beaconset.beaconset;


import com.minew.beaconset.BluetoothState;
import com.minew.beaconset.MinewBeacon;
import com.minew.beaconset.MinewBeaconManager;
import com.minew.beaconset.MinewBeaconManagerListener;
import com.minew.beaconset.App;
import com.minew.beaconset.bean.LocaltionLog;
import com.minew.beaconset.bean.MinewBeaconTimes;
import com.minew.beaconset.dobackground.CleanLocalDataTask;
import com.minew.beaconset.dobackground.GetLocalDataTask;
import com.minew.beaconset.dobackground.SaveLocalDataTask;
import com.minew.beaconset.downtime.DownTimer;
import com.minew.beaconset.downtime.DownTimerListener;
import com.minew.beaconset.permission.PermissionManager;
import com.minew.beaconset.task.TaskManager;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Beacon管理工具
 */
public class BeaconsetManager {
    /**
     * 检查频率
     */
    private long checkFrequency = 1000*5;
    /**
     * 计算出现频率
     * 处理波动
     * mac -> distant -> times
     */
    private Map<String, Map<Float, MinewBeaconTimes>> temp = new HashMap<>();

    /**
     * 最低/最高 Rssi
     */
    private int minRssi,maxRssi;

    /**
     * 设置信号范围
     * @param minRssi
     * @param maxRssi
     */
    public void setRssiRange(int minRssi,int maxRssi){
        this.minRssi = minRssi;
        this.maxRssi = maxRssi;
    }
    /**
     * 统计出现次数
     * mac->times
     */
    private Map<String,MinewBeacon> beacons = new HashMap<>();
    private int lastCount = 0;
    private  MinewBeaconManager mMinewBeaconManager;
    private DownTimer downTimer;
    private static BeaconsetManager beaconsetUtil;
    public static BeaconsetManager getInstance(){
        if(beaconsetUtil==null){
            synchronized (BeaconsetManager.class){
                if(beaconsetUtil==null){
                    beaconsetUtil = new BeaconsetManager();
                    beaconsetUtil.init();
                }
            }
        }
        return beaconsetUtil;
    }

    /**
     * 初始化
     */
    private void init(){
        downTimer = new DownTimer();
        downTimer.setListener(new DownTimerListener() {
            @Override
            public void onTick(long millisUntilFinished) {}
            @Override
            public void onFinish() { toCheckData(); }
        });
        mMinewBeaconManager = MinewBeaconManager.getInstance(App.getApp());
        mMinewBeaconManager.startService();
        mMinewBeaconManager.setMinewbeaconManagerListener(new MinewBeaconManagerListener() {
            @Override
            public void onUpdateBluetoothState(BluetoothState state) {
                switch (state) {
                    case BluetoothStatePowerOff:
                        stopService();
                        break;
                    case BluetoothStatePowerOn:
                        startScan();
                        break;
                }
            }

            @Override
            public void onRangeBeacons(List<MinewBeacon> list) {
                for(MinewBeacon beacon:list){
                    if(temp.get(beacon.getMacAddress())!=null){
                        Map<Float,MinewBeaconTimes> map = temp.get(beacon.getMacAddress());
                        if(map.get(beacon.getDistance())!=null){
                            MinewBeaconTimes times = map.get(beacon.getDistance());
                            times.setMinewBeacon(beacon);
                            times.setTimes(times.getTimes()+1);
                            map.put(beacon.getDistance(),times);
                        }else{
                            MinewBeaconTimes times = new MinewBeaconTimes();
                            times.setTimes(1);
                            times.setMinewBeacon(beacon);
                            map.put(beacon.getDistance(),times);
                        }
                        temp.put(beacon.getMacAddress(),map);
                    }else{
                        Map<Float,MinewBeaconTimes> map = new HashMap<>();
                        MinewBeaconTimes times = new MinewBeaconTimes();
                        times.setTimes(1);
                        times.setMinewBeacon(beacon);
                        map.put(beacon.getDistance(),times);
                        temp.put(beacon.getMacAddress(),map);
                    }
                }
            }

            @Override
            public void onAppearBeacons(List<MinewBeacon> list) {
            }

            @Override
            public void onDisappearBeacons(List<MinewBeacon> list) {
            }
        });
        startScan();
    }

    /**
     * 检查数据
     */
    private void toCheckData(){
        SaveLocalDataTask saveLocalDataTask = new SaveLocalDataTask();
        saveLocalDataTask.set("temp",temp);
        saveLocalDataTask.set("beacons",beacons);
        saveLocalDataTask.set("minRssi",minRssi);
        saveLocalDataTask.set("maxRssi",maxRssi);
        TaskManager.getInstance().exec(saveLocalDataTask, task -> {
            if(task.success()){
                beacons = task.getParam("beacons");
            }
            //清除缓存
            temp.clear();
            startDown();
        });
    }

    /**
     * 获取本地数据
     */
    public void getLocationData(OnLocationDataCallback callback){
        GetLocalDataTask getLocalDataTask = new GetLocalDataTask();
        TaskManager.getInstance().exec(getLocalDataTask,task -> {
            if(task.success()){
                Map<String,List<LocaltionLog>> map = task.getResult();
                if(callback!=null){
                    callback.onData(map);
                }
            }
        });
    }

    /**
     * 清除数据
     */
    public void cleanData(PermissionManager.AfterDo afterDo){
        TaskManager.getInstance().exec(new CleanLocalDataTask(),task->{
            if(afterDo!=null){
                afterDo.onAfter();
            }
        });
    }
    public interface OnLocationDataCallback{
        void onData(Map<String,List<LocaltionLog>> map);
    }
    /**
     * 开始扫描
     */
    public void startScan(){
        if(beaconsetUtil==null){
            return;
        }
        mMinewBeaconManager.startScan();
        if(downTimer==null){
            return;
        }
        startDown();
    }

    /**
     * 开始倒计时
     */
    private void startDown(){
        downTimer.startDown(checkFrequency,1000);
    }

    /**
     * 设置滤波频率
     * @param checkFrequency
     */
    public void setCheckFrequency(long checkFrequency){
        this.checkFrequency = checkFrequency;
    }

    /**
     * 停止服务
     */
    public void stopService(){
        if(beaconsetUtil==null){
            return;
        }
        mMinewBeaconManager.stopService();
    }

}
